package com.i72.governance.init;


import com.i72.basic.tools.YAMLHelper;
import com.i72.basic.consts.Consts;
import com.i72.governance.service.bean.ServiceConfig;
import com.i72.governance.service.helper.NacosConfigHelper;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.Ordered;
import org.springframework.core.env.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;

import java.util.*;


@Conditional(GovernanceConfigurationMarket.class)
//@ComponentScan("com.i72.basic")
@ComponentScan("com.i72.governance")
@Import(GovernanceServiceInit.class)
public class GovernanceDefaultInit extends PropertySourcesPlaceholderConfigurer implements ApplicationContextAware, Ordered {



    private final static String GOVERNANCE_SERVER_ADDRESS_KEY = "governance.service.address";

    private static NacosConfigHelper configHelper = null;
    private final static Object LOCK = new Object();

    private BeanFactory beanFactory = null;

    private Environment environment = null;


    private ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;

        //初始化好之后。开始监听
        if(configHelper!=null){

            configHelper.setApplicationContext(applicationContext);
            //监听配置
            configHelper.watchConfig(this.environment.getProperty(Consts.GOVERNANCE_SERVER_SERVICENAME),"");
        }
    }

    @Override
    public void setEnvironment(Environment e) {
        super.setEnvironment(e);

        this.environment = e;

        //空值不解析，减少报错，踏破铁鞋无觅处得来全不费工夫
        this.ignoreUnresolvablePlaceholders=true;

        //加载默认配置
        initDefaultConfig();

        //加载远程配置
        loadRemoteConfig();




    }

    /**
     * 加载远程配置
     */
    private void loadRemoteConfig(){

        String address = this.environment.getProperty(GOVERNANCE_SERVER_ADDRESS_KEY);

        //这个时候必须用beanFactory,而不是applicationContext
        //因为beanFactory比applicationContext事件早注入，所以这也必须重写
        //setBeanFactory方法的原因

        ServiceConfig serviceConfig = this.beanFactory.getBean(ServiceConfig.class);
        serviceConfig.setAddress(address);

        initConfigHelper(serviceConfig);

        if(configHelper!=null){

            //获取配置
            String value = configHelper.getConfig(this.environment.getProperty(Consts.GOVERNANCE_SERVER_SERVICENAME),"");
            Properties properties = YAMLHelper.yamlToProperties(value);

            if(properties!=null && properties.keySet().size()>0) {

                PropertySource p = new PropertiesPropertySource("remoteConfig", properties);

                StandardEnvironment environment = (StandardEnvironment) this.environment;
                MutablePropertySources m = environment.getPropertySources();
                m.addLast(p);
            }
        }

    }

    private void initConfigHelper(ServiceConfig serviceConfig){
        if(configHelper==null){
            synchronized (LOCK){
                if(configHelper==null){
                    if(serviceConfig!=null) {
                        configHelper = new NacosConfigHelper();
                        configHelper.setServiceConfig(serviceConfig);
                        configHelper.initConfig();
                    }
                }
            }
        }
    }

    /**
     * 加载默认配置
     */
    private void initDefaultConfig(){


        //配置优先权,当前应用，环境变量，默认配置

        Environment e = this.environment;

        //读取默认yaml文件为properties
        Resource resource = new ClassPathResource(Consts.GOVERNANCE_DEFAULT_CONFIG_PATH);
        Properties properties = null;
        PropertySource p = null;
        if (resource != null && resource.exists()) {
            properties = YAMLHelper.yamlToProperties(resource);
            if(properties!=null && properties.keySet().size()>0){
                //默认配置文件
                p = new PropertiesPropertySource("governanceDefault", properties);
            }
        }



        //添加默认配置
        StandardEnvironment environment = (StandardEnvironment) e;
        MutablePropertySources m = environment.getPropertySources();

        PropertySource p2 = null;

        Map mm = environment.getSystemEnvironment();

        if (mm.containsKey(Consts.GOVERNANCE_SERVER_ADDRESS)) {
            if (mm.get(Consts.GOVERNANCE_SERVER_ADDRESS) != null) {
                String value = mm.get(Consts.GOVERNANCE_SERVER_ADDRESS).toString();
                if (!StringUtils.isEmpty(value)) {
                    //添加环境变量配置文件
                    Properties properties2 = new Properties();
                    properties2.setProperty(GOVERNANCE_SERVER_ADDRESS_KEY, value);

                    p2 = new PropertiesPropertySource("governance2", properties);
                }
            }
        }

        if(p!=null) {
            m.addLast(p);
            //加载末尾
        }

        if (p2 != null) {
            //加入到默认配置之前
            m.addBefore("governanceDefault", p2);
        }





    }






    @Override
    public void setBeanFactory(BeanFactory factory) {
        super.setBeanFactory(factory);
        this.beanFactory =factory;


    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE+3;
    }
}
